#ifndef event_waiter_frame_hpp
#define event_waiter_frame_hpp

#include <iostream>
#include <boost/thread.hpp>
#include <boost/interprocess/ipc/message_queue.hpp>   
#include <string>
#include <boost/array.hpp>

using namespace boost::interprocess;  

// UTF-8


enum wait_resource_over_reason{
t_resource_for_funcpartdown_gotready=1,
    t_cancel_funcpartdown,
};


enum s_event_waiter{
s_null=1,
    s_start_init,
        s_waitevent,
            s_dofunc_part_up,
                s_dofunc_part_down,
                    s_wait_resource,
                        s_cancel_func_part_down,
};

class event_waiter;

class event_waiter_para{
public:
    void* para;

};

typedef void(*pfunc)(event_waiter_para*p);

typedef boost::array<int, 6>  array_t; 


// 本事件通信类应该支持一个事件的上半部、下半部方法的注册，以及cancel_event方法的注册。
//                                    (或者不采用注册，而借助信号与槽)
// 外界可以通过本类对外提供的wake_event接口触发本类的do_event方法的执行。
// do_event方法内部如果需要等待资源，则可以调用wait_resource方法进行等待，
// 外界使用wake_resource方法通知资源到位。
class event_waiter{

    int step;

    message_queue *p_mq_event;
    message_queue *p_mq_resource;


    int p_realtime_para_partdown;
    int p_realtime_para_cancelpartdown;


    int wait_event(int& r_event_t); 
    int wait_resource(int* resource_t, int* cancel_reason);


    static int i_mq_name;
    std::string mq_event;    //"mq_event"
    std::string mq_resource; //"mq_resource"

    array_t func_parts; 
    void do_event_loop_thread();
    void wake_resource(int* resource_t);
public:

    event_waiter(int state);
    void create_event_loop();

    void wake_event(int event_t);
    void wake_resource(void);
    void cancel_funcpartdown(int cancel_reason); 

    // 执行事件的上半部: 使用调用该函数时的传入参数  GB2312
    void event_waiter_register_func_part_up(pfunc pfunc,  event_waiter_para* para);

    // 调用该函数时，如果传入参数NULL，则使用实时传入的参数。优先使用调用函数时传入的参数
	void event_waiter_register_func_part_down(pfunc pfunc,  event_waiter_para* para);
    //同上，优先使用调用函数时传入的参数
    void event_waiter_register_cancel_funcpartdown(pfunc pfunc,  event_waiter_para* para);

};


#endif

